/* part1test.c
 * test the syscall for the lock and condition
 */
#include "utility.h"
int clL1,clL2,cl_L3;

int alL1, alL2,alL3;

int rlL1,rlL2,rlL3,rlL4;
int rlcv1, rlcv2, rllock1,rllock2;
int rt2overcv, rt2overlock;

int dlL1, dlL2,dlL3,dlL4;

int cvL1,cvL2,cvL3;
int ccC1,ccC2,ccC3,ccC4;


int scC1,scC2,scC3,scC4;
int wcC1,wcC2,wcC3,wcC4;
int bcC1,bcC2,bcC3,bcC4;
int dcC1,dcC2,dcC3,dcC4;

void CLT1()
{
    int i;
    char * lockname1="lock1";
    clL1=CreateLock(lockname1,5);
    if(clL1!=-1)
        Printf("CLT1 lockname is 5, create it succussfully, return %d \n",clL1);
    else
    {
        Printf("CLT1 lockname is 5,  could not create it, return %d\n",clL1);
    }
}

void CLT2()
{
    int i;
    char  lockname2[300];
    for(; i<300; i++)
        lockname2[i]='l';
    clL2=CreateLock(lockname2,300);
    if(clL2!=-1)
        Printf("CLT2 lockname is 300, create it succussfully, return %d \n",clL2);
    else
    {
        Printf("CLT2 lockname is 300,  could not create it, return %d\n",clL2);
    }
}


void AT1()
{
    alL1=CreateLock("alL1", 4);
    Printf("AT1 try to acquire a correct lock\n");
    AcquireLock(alL1);
    Printf("AT1 acquire a correct lock successfully\n");
}

void AT2()
{
    int result;
    alL2=100;
    Printf("AT2 try to acquire a lock that not initiated \n");
    result= AcquireLock(alL2);
    if(-1!=result)
        Printf("AT2 acquire a not initiated  lock successfully\n");
    else
        Printf("AT2 try to acquire a lock that not initiated, but failed return %d \n", result);
}
void AT3()
{
    int result;
    alL3=-1;
    Printf("AT3 try to acquire a lock that number is -1\n");
    result= AcquireLock(alL3);
    if(-1!=result)
        Printf("AT3 acquire -1 lock successfully\n");
    else
        Printf("AT3 try to acquire -1 lock , but failed, return %d \n",result);
}
/*thread try to release a owned lock*/
void RT1()
{
    int result;
    rlL1=CreateLock("rlL1", 4);
    /*Printf("thread try to acquire a correct lock\n");*/
    result= AcquireLock(rlL1);
    if(-1!=result)
        Printf("RT1 acquire  lock successfully\n");
    else
        Printf("RT1 try to acquire  lock , but failed, return %d \n",result);
    result= ReleaseLock(rlL1);
    if(-1!=result)
        Printf("RT1 release  lock successfully\n");
    else
        Printf("RT1 try to release  lock , but failed, return %d \n",result);
}

/*thread try to release a not-owned lock*/
/*thread rt2_t0 try to release a lock it do not own, the kenel would tell us that it does not have the lock*/
void RT2_t0()
{
    int result=0;
    AcquireLock(rllock1);
    WaitCV(rllock1, rlcv1);
    ReleaseLock(rllock1);
    Printf("RT2_t0 try to release the lock that hold by RT2_t1\n");
    ReleaseLock(rlL2);
    AcquireLock(rt2overlock);
    SignalCV(rt2overlock,rt2overcv);
    ReleaseLock(rt2overlock);
    Printf("RT2_t0 thread is goint to Exit\n");
    Exit(0);
}
/*thread rt2_t1 would acquire the lock, and signal the rt2_t0 to start*/
void RT2_t1()
{
    int result=0;
    AcquireLock(rllock1);
    result=AcquireLock(rlL2);
    Printf("RT2_t1 get the lock rlL2\n");
    SignalCV(rllock1, rlcv1);
    ReleaseLock(rllock1);
    Printf("RT2_t1 thread is goint to Exit\n");
    Exit(0);
}
void RT2()
{
    rt2overcv=CreateCV("overcv",8);
    rt2overlock=CreateLock("overlock", 8);

    rllock1=CreateLock("rllock1", 7);
    rlcv1=CreateCV("rlcv1", 5);
    rlL2=CreateLock("rlL2", 4);
    Printf("RT2 create rt2_t0\n");
    Fork(RT2_t0);
    Printf("RT2_t0 create rt2_t1\n");
    Fork(RT2_t1);
    AcquireLock(rt2overlock);
    Printf("main wait for rt2over\n");
    WaitCV( rt2overlock,rt2overcv);
    ReleaseLock(rt2overlock);
}

/*thread try to release a non-initiated lock*/

void RT3()
{
    int result;
    rlL3=6666;
    Printf("RT3 try to release a lock not initiated \n");
    result=ReleaseLock(rlL2);
    if(-1!=result)
        Printf("RT3 release  lock successfully\n");
    else
        Printf("RT3 try to release  lock 100 , but failed, return %d\n", result);
}

/*thread try to release a -1 lock*/
void RT4()
{
    int result;
    rlL4=-1;
    Printf("RT4 try to release a lock -1 \n");
    result=ReleaseLock(rlL4);
    if(-1!=result)
        Printf("RT4 release  lock successfully\n");
    else
        Printf("RT4 try to release  lock -1 , but failed, return %d\n", result);
}

/*thread try to delete a owned lock*/
void DT1()
{
    int result;
    dlL1=CreateLock("dlL1", 4);
    result= AcquireLock(dlL1);
    if(-1!=result)
        Printf("DT1 acquire  lock successfully\n");
    else
        Printf("DT1 try to acquire  lock , but failed, return %d\n", result);
    result= ReleaseLock(dlL1);
    if(-1!=result)
        Printf("DT1 release  lock successfully\n");
    else
        Printf("DT1 try to release  lock , but failed, return %d\n", result);
    Printf("DT1 try to delete a not used  lock  \n");
    result= DeleteLock(dlL1);
    if(-1!=result)
        Printf("DT1 delete  lock successfully\n");
    else
        Printf("DT1 try to delete  lock , but failed, return %d\n", result);
}

/*thread try to release a used lock*/

void DT2()
{
    int result;
    dlL2=CreateLock("dlL2", 4);
    Printf("DT2 try to acquire a correct lock\n");
    result= AcquireLock(dlL2);
    if(-1!=result)
        Printf("DT2 acquire  lock successfully\n");
    else
        Printf("DT2 try to acquire  lock , but failed, return %d\n", result);
    Printf("DT2 try to delete a using  lock\n");
    result= DeleteLock(dlL2);
    if(-1!=result)
        Printf("DT2 delete  lock successfully\n");
    else
        Printf("DT2 try to delete  lock , but failed, return %d\n", result);
}
/*thread try to release a non-initiated lock*/

void DT3()
{
    int result;
    dlL3=100;
    Printf("DT3 try to delete a lock not initiated \n");
    result=DeleteLock(dlL3);
    if(-1!=result)
        Printf("DT3 delete  lock successfully\n");
    else
        Printf("DT3 try to delete non-initiated  lock , but failed, return %d\n", result);
}

/*thread try to release a -1 lock*/
void DT4()
{
    int result;
    dlL4=-1;
    Printf("DT4 try to delete a lock -1 \n");
    result=ReleaseLock(dlL4);
    if(-1!=result)
        Printf("DT4 delete  lock successfully\n");
    else
        Printf("DT4 try to delete -1  lock , but failed, return %d\n", result);
}

void CC1()
{
    int i;
    char * cvname1="clL1";
    ccC1=CreateCV(cvname1,4);
    if(ccC1!=-1)
        Printf("CC1 name length 4 is correct, create it succussfully, return %d \n",ccC1);
    else
    {
        Printf("CC1 name length 4 is not correct,  could not create it, return %d\n",ccC1);
    }
}

void CC2()
{
    int i;
    char cvname[300];
    for(i=0; i<300; i++)
        cvname[i]='c';
    Printf("CC2 try to create condition lenght is 300\n");
    ccC2=CreateCV(cvname,300);
    if(ccC2!=-1)
        Printf("CC2 name length 300 is correct, create it succussfully, return %d \n",ccC2);
    else
    {
        Printf("CC2 name length 300 is not correct,  could not create it, return %d\n",ccC2);
    }

}

void SC1()
{
    int i;
    int result;
    char * cvname="sc";
    char * lockname="locksc";
    scC1=CreateCV(cvname,2);
    cvL1=CreateLock(lockname,6);
    AcquireLock(cvL1);
    Printf("SC1 try to signal a created condition\n");
    result= SignalCV(cvL1, scC1);
    if(result!=-1)
    {
        Printf("SC1 signal sucessfully  \n");
    }
    else
    {
        Printf("SC1 signal failed\n");
    }
    ReleaseLock(cvL1);
    DeleteLock(cvL1);
}
void SC2()
{
    int i;
    int result;
    char * cvname="sc";
    char * lockname="locksc";
    scC2=-1;
    cvL2=CreateLock(lockname,6);
    AcquireLock(cvL2);
    Printf("SC2 try to signal a non-created condition\n");
    result= SignalCV(cvL2, scC2);
    if(result!=-1)
    {
        Printf("SC2 signal sucessfully  \n");
    }
    else
    {
        Printf("SC2 signal failed\n");
    }
    ReleaseLock(cvL2);
    DeleteLock(cvL2);
}

void BC1()
{
    int i;
    int result;
    char * cvname="bc";
    char * lockname="locksc";
    bcC1=CreateCV(cvname,2);
    cvL1=CreateLock(lockname,6);
    AcquireLock(cvL1);
    Printf("BC1 try to broadcast a created condition\n");
    result= BroadcastCV(cvL1, bcC1);
    if(result!=-1)
    {
        Printf("BC1 broadcast sucessfully  \n");
    }
    else
    {
        Printf("BC1 broadcast failed\n");
    }
    ReleaseLock(cvL1);
}
void BC2()
{
    int i;
    int result;
    char * cvname="bc";
    char * lockname="lockbc";
    bcC2=-1;
    cvL2=CreateLock(lockname,6);
    AcquireLock(cvL2);
    Printf("BC2 try to broadcast a non-created condition\n");
    result= BroadcastCV(cvL2, bcC2);
    if(result!=-1)
    {
        Printf("BC2 broadcast sucessfully  \n");
    }
    else
    {
        Printf("BC2 broadcast failed\n");
    }
    ReleaseLock(cvL2);
}

void DC1()
{
    int i;
    int result;
    char * cvname="dc1";
    dcC1=CreateCV(cvname,3);
    Printf("DC1 try to delete a created condition %d\n",dcC1);
    result=DeleteCV(dcC1);
    if(result!=-1)
    {
        Printf("DC1 delete sucessfully  \n");
    }
    else
    {
        Printf("DC1 delete failed\n");
    }
}
void DC2()
{
    int i;
    int result;
    dcC2=-1;
    Printf("DC2 try to delete a -1 condition\n");
    result=DeleteCV(dcC2);
     if(result!=-1)
    {
        Printf("DC2 delete sucessfully  \n");
    }
    else
    {
        Printf("DC2 delete failed\n");
    }
}

void mlt1(){
    Printf("mlt1 tests for a process try to acquire a lock belongs to others\n");
    Exec("../test/lockMulti",25);
}

int main()
{
    CLT1();
    CLT2();
    AT1();
    AT2();
    AT3();

    RT1();
    RT2();
    RT3();
    RT4();

    DT1();
    DT2();
    DT3();
    DT4();

    CC1();
    CC2();
    SC1();
    SC2();


    BC1();
    BC2();

    DC1();
    DC2();

    mlt1();

    
    Printf("main thread is going to yield\n");
    Yield();
    Printf("main thread is returing back from yield\n");
    Exit(0);

}
